#include "bt_hal.h"
#include "ms_hal_ble.h"
#include <stdlib.h>

static int ble_stack_status = 0;
ms_hal_ble_stack_callback_t ms_hal_ble_stack_callback = NULL;
ms_hal_result_t ms_hal_ble_stack_start(void)
{
    if (ble_stack_status == LD_HAL_BLE_STATUS_ON)
    {
        return MS_HAL_RESULT_SUCCESS;
    }
    ms_hal_ble_stack_msg_t msg;
    bzero(&msg, sizeof(msg));
    if (0 == bt_init())
    {
        ble_stack_status = LD_HAL_BLE_STATUS_ON;
        msg.event_type = MS_HAL_BLE_STACK_EVENT_STACK_READY;
        if (ms_hal_ble_stack_callback)
            ms_hal_ble_stack_callback(msg);
        return MS_HAL_RESULT_SUCCESS;
    }
    msg.event_type = MS_HAL_BLE_STACK_EVENT_STACK_FAIL;
    if (ms_hal_ble_stack_callback)
        ms_hal_ble_stack_callback(msg);
    return MS_HAL_RESULT_ERROR;
}

ms_hal_result_t ms_hal_ble_stack_stop(void)
{
    if (ble_stack_status == LD_HAL_BLE_STATUS_OFF)
    {
        return MS_HAL_RESULT_SUCCESS;
    }
    if (0 == bt_deinit())
    {
        ms_hal_ble_stack_stop_service_clean();
        ble_stack_status = LD_HAL_BLE_STATUS_OFF;
        ms_hal_ble_stack_msg_t msg;
        bzero(&msg, sizeof(msg));
        msg.event_type = MS_HAL_BLE_STACK_EVENT_STACK_STOP;
        if (ms_hal_ble_stack_callback)
            ms_hal_ble_stack_callback(msg);
        return MS_HAL_RESULT_SUCCESS;
    }
    return MS_HAL_RESULT_ERROR;
}

uint8_t ms_hal_ble_get_stack_status(void)
{
    return ble_stack_status;
    ;
}

ms_hal_result_t ms_hal_ble_set_stack_event_register(ms_hal_ble_stack_callback_t event_handler)
{
    if (event_handler)
    {
        ms_hal_ble_stack_callback = event_handler;
        return MS_HAL_RESULT_SUCCESS;
    }
    else
    {
        return MS_HAL_RESULT_ERROR;
    }
}

//接口不可用
uint16_t ms_hal_ble_legacy_adv_start(ms_hal_ble_gap_adv_params *param, ms_hal_ble_gap_adv_data *adv_data)
{
    uint16_t ret = ble_legacy_adv_start(param, adv_data, 1);
    if (0 == ret)
    {
        ms_hal_ble_stack_msg_t msg;
        bzero(&msg, sizeof(msg));
        msg.event_type = MS_HAL_BLE_STACK_EVENT_ADV_ON;
        if (ms_hal_ble_stack_callback)
            ms_hal_ble_stack_callback(msg);
    }
    return ret;
}

//接口不可用
ms_hal_result_t ms_hal_ble_legacy_adv_update(uint16_t adv_handle, ms_hal_ble_gap_adv_data *adv_data)
{
    if (ble_adv_status(adv_handle))
    {
        ble_legacy_adv_start(NULL, adv_data, 1);
    }
    else
    {
        ble_legacy_adv_start(NULL, adv_data, 0);
    }
    return MS_HAL_RESULT_SUCCESS;
    ;
}

//接口不可用
ms_hal_result_t ms_hal_ble_adv_stop(uint16_t handle)
{
    uint16_t ret = ble_legacy_adv_stop(handle);
    if (0 == ret)
    {
        ms_hal_ble_stack_msg_t msg;
        bzero(&msg, sizeof(msg));
        msg.event_type = MS_HAL_BLE_STACK_EVENT_ADV_OFF;
        if (ms_hal_ble_stack_callback)
            ms_hal_ble_stack_callback(msg);
    }
    return ret;
    ;
}

//接口不可用
uint8_t ms_hal_ble_adv_status(uint16_t handle)
{
    return ble_adv_status(handle);
    ;
}

uint8_t ms_hal_ble_gap_connect_status(uint16_t conn_hdl)
{
    return get_device_from_id(conn_hdl);
    ;
}

ms_hal_result_t ms_hal_ble_gap_disconnect(uint16_t conn_hdl)
{
    ble_gatt_data_t *device = get_addr_from_id(conn_hdl);
    if (device)
    {
        if (device->is_slave == 0)
        {
            char addr_buf[32] = {0};
            sprintf(addr_buf, "%02x:%02x:%02x:%02x:%02x:%02x", device->addr[0], device->addr[1], device->addr[2], device->addr[3],
                    device->addr[4], device->addr[5]);
            bt_manager_gatt_client_disconnect(addr_buf);
        }
        else
            bt_manager_le_disconnect();
        return MS_HAL_RESULT_SUCCESS;
    }
    else
    {
        return MS_HAL_RESULT_ERROR;
    };
}

ms_hal_result_t ms_hal_ble_scan_start(ms_hal_ble_scan_params_t *params, ms_hal_ble_scan_callback_t function)
{
    return ble_scan_start(params, function);
    ;
}

ms_hal_result_t ms_hal_ble_scan_stop(void)
{
    return ble_scan_stop();
    ;
}

uint8_t ms_hal_ble_scan_status(void)
{
    return get_ble_scan_status();
    ;
}

//接口不可用
ms_hal_result_t ms_hal_ble_gatt_service_add(ms_hal_ble_service_t *service)
{
    ble_gatt_service_add(service);
    return MS_HAL_RESULT_SUCCESS;
}

ms_hal_result_t ms_hal_ble_discovery_all_service(uint16_t conn_hdl)
{
    return ble_discovery_all_service(1, conn_hdl);
    ;
}

//此接口直接在ms_hal_ble_discovery_all_service里实现了
ms_hal_result_t ms_hal_ble_discovery_all_char(uint16_t conn_hdl, uint16_t start_hdl, uint16_t end_hdl)
{
    return ble_discovery_all_service(2, conn_hdl);
}

//此接口直接在ms_hal_ble_discovery_all_service里实现了
ms_hal_result_t ms_hal_ble_discovery_all_descriptor(uint16_t conn_hdl, uint16_t start_hdl, uint16_t end_hdl)
{
    return ble_discovery_all_service(3, conn_hdl);
}

//接口不可用
ms_hal_result_t ms_hal_ble_gatt_data_send(uint16_t conn_hdl, ms_hal_ble_gatts_attr_handle_t *handle, uint8_t *data, uint16_t len)
{
    return ble_gatt_data_send(conn_hdl, handle, data, len);
}

ms_hal_result_t ms_hal_ble_gatt_write(uint8_t type, uint16_t conn_hdl, uint16_t att_handle, uint16_t len, uint8_t *data)
{
    return ble_gatt_write(type, conn_hdl, att_handle, len, data);
}

ms_hal_result_t ms_hal_ble_set_cccd(uint16_t cccd_value, uint16_t conn_hdl, uint16_t att_handle)
{
    unsigned char data[2] = {0};
    data[0] = cccd_value & 0xff;
    data[1] = (cccd_value >> 8) & 0xff;
    int ret = bt_manager_gatt_client_write_request(conn_hdl, att_handle, data, 2);
    if (!ret)
    {
        return MS_HAL_RESULT_SUCCESS;
    }
    else
    {
        return MS_HAL_RESULT_ERROR;
    }
}

uint16_t ms_hal_ble_mtu_get(uint16_t conn_hdl)
{
    return bt_manager_gatt_server_get_mtu();
    ;
}

ms_hal_result_t ms_hal_ble_conn_start(ms_hal_ble_conn_param_t *param, ms_hal_ble_addr_t *target)
{
    if (!target)
    {
        return MS_HAL_RESULT_ERROR;
    }
    if (!param)
    {
        return MS_HAL_RESULT_ERROR;
    }
    int ret = ble_conn_start(param, target);
    if (ret)
    {
        return MS_HAL_RESULT_ERROR;
    }
    else
    {
        return MS_HAL_RESULT_SUCCESS;
    }
}

//接口不可用，不支持停止连接动作
ms_hal_result_t ms_hal_ble_conn_stop(void)
{
    ;
    ;
}

ms_hal_result_t ms_hal_ble_get_public_mac_address(uint8_t *p_mac)
{
    char mac_buf[64] = {0};
    int ret = bt_manager_get_adapter_address(mac_buf);
    if (strlen(mac_buf) == 17 && mac_buf[2] == ':')
    {
        for (int i = 0; i < 6; i++)
        {
            char buf[3] = {0};
            memcpy(buf, &mac_buf[i * 3], 2);
            p_mac[i] = strtoull(buf, NULL, 16);
        }
    }
    else
    {
        return MS_HAL_RESULT_ERROR;
    }
    if (ret)
    {
        return MS_HAL_RESULT_ERROR;
    }
    return MS_HAL_RESULT_SUCCESS;
}

ms_hal_result_t ms_hal_ble_set_device_name(uint8_t *name, uint8_t len)
{
    return set_ble_name(name, len);
}